﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.IO;
using System.Collections;

namespace ImageUploader.domain
{
    public class User
    {
        public SearchResult SearchResult
        { get; set; }
        private int accountEnabled;
        private string cn, sAMAccountName,userPrincipalName,firstName, telnr, initials, description, homepage,lastName, displayName, mail, place, office, postalCode, postOfficeBox,country, province,street ;
        private byte[] jpgPhoto;
        
        public DirectoryEntry DirectoryEntry
        {
            get
            {
                 return SearchResult.GetDirectoryEntry();
            }
        }

        public User(SearchResult sr)
        {
            this.SearchResult = sr;
        }

        public User()
        {
            try
            {
                this.accountEnabled = 1;
                this.sAMAccountName = "New account";
                this.cn = "New account";
                this.userPrincipalName = "New account"; //invullen?
                this.firstName = "";
                this.lastName = "";
                this.initials = "";
                this.displayName = "";
                //Algemene gegevens
                this.description = "";
                this.office = "";
                this.telnr = "";
                this.mail = "";
                this.homepage= "";
                this.jpgPhoto = new Byte[1];
                //this.jpgPhoto = "";
                //Adresgegevens
                this.street = "";
                this.postOfficeBox = "";
                this.place = "";
                this.province = "";
                this.postalCode = "";
                this.country = "";
                

            }
            catch (Exception exep)
            { }
        }

        public void Delete()
        {
                //.Children.Remove(toDelete);
            //de.Parent.Children.Remove(de);
        }

        public void RenameCurrentUser(String newName)
        {
            DirectoryEntry de = SearchResult.GetDirectoryEntry();
            if (!de.Properties["cn"].Value.ToString().Equals(newName))
            {
                de.Rename("CN=" + newName);
                de.CommitChanges();
            }
       
        }

        public User(String sAMAccountName,String userPrincipalName, String cn,String firstName, String telnr, String initials, String description, String homepage,String lastName, String street, String displayName, String place, String userName, String mail, String province,String office, String postalCode, String postOfficeBox,String country)
        {
            //Namen
            this.accountEnabled = 1;
            this.SAMAccountName = sAMAccountName;
            this.CN = cn;
            this.UserPrincipalName = userPrincipalName;
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Initials = initials;
            this.DisplayName = displayName;
            //Algemene gegevens
            this.Description = description;
            this.Office = office;
            this.Telnr = telnr;
            this.Mail = mail;
            this.HomePage = homepage;
            //Adresgegevens
            this.Street = street;
            this.PostOfficeBox = postOfficeBox;
            this.Place = place;
            this.Province = province;
            this.PostalCode = postalCode;
            this.Country = country;
            this.JpgPhoto = jpgPhoto;

        }

        public string CN
        {
            get
            {
                if (cn == null)
                    cn = SearchResult.Properties["cn"].Count > 0 ? SearchResult.Properties["cn"][0].ToString() : "";
                return cn;
            }
            set 
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                if (!de.Properties["cn"].Value.ToString().Equals(value.ToString()))
                {
                    de.Rename("CN=" + value);
                    de.CommitChanges();
                }
                
            }
        }

        public string SAMAccountName
        {
            get
            {
                if (sAMAccountName == null)
                    sAMAccountName = SearchResult.Properties["sAMAccountName"].Count > 0 ? SearchResult.Properties["sAMAccountName"][0].ToString() : "";
                return sAMAccountName;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["sAMAccountName"].Clear();
                if (value != "")
                {
                    de.Properties["sAMAccountName"].Insert(0, value);
                    sAMAccountName = value;
                    
                }
                //else
                    //sAMAccountName = null;
                //cn? nie zeker
                de.CommitChanges();
            }
        }

        public string UserPrincipalName
        {
            get
            {
                if (userPrincipalName == null)
                    userPrincipalName = SearchResult.Properties["userPrincipalName"].Count > 0 ? SearchResult.Properties["userPrincipalName"][0].ToString() : "";
                return userPrincipalName;
            }
            set 
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["userPrincipalName"].Clear();
                if (value != "")
                {
                    de.Properties["userPrincipalName"].Insert(0, value);
                    userPrincipalName = value;
                }
                else
                    userPrincipalName = null;

                de.CommitChanges();
            }
        }

        public string Description
        {
            get
            {
                if (description == null)
                    description = SearchResult.Properties["description"].Count > 0 ? SearchResult.Properties["description"][0].ToString() : "";
                return description;
            }
            set 
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["description"].Clear();
                if (value != "")
                {
                    de.Properties["description"].Insert(0, value);
                    description = value;
                }
                else
                    description = null;

                de.CommitChanges();
            }
        }
        public int AccountEnabled
        {
            get
            {
                if (accountEnabled == null)
                    accountEnabled = SearchResult.Properties["AccountEnabled"].Count > 0 ? (int)SearchResult.Properties["AccountEnabled"][0] : 0;
                return accountEnabled;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["AccountEnabled"].Clear();
                if (value != 0)
                {
                    de.Properties["AccountEnabled"].Insert(0, value);
                    accountEnabled = value;
                }
                else
                    accountEnabled = 1;

                de.CommitChanges();
            }
        }

        public string Initials
        {
            get
            {
                if (initials == null)
                    initials = SearchResult.Properties["initials"].Count > 0 ? SearchResult.Properties["initials"][0].ToString() : "";
                return initials;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["initials"].Clear();
                if (value != "")
                {
                    de.Properties["initials"].Insert(0, value);
                    initials = value;
                }
                else
                    initials = null;

                de.CommitChanges();
            }
        }

        public string Telnr
        {
            get
            {
                if (telnr == null)
                    telnr = SearchResult.Properties["telephoneNumber"].Count > 0 ? SearchResult.Properties["telephoneNumber"][0].ToString() : "";
                return telnr;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["telephoneNumber"].Clear();
                if (value != "")
                {
                    de.Properties["telephoneNumber"].Insert(0, value);
                    telnr = value;
                }
                else
                    telnr = null;

                de.CommitChanges();
            }
        }

        public string HomePage
        {
            get
            {
                if (homepage == null)
                    homepage = SearchResult.Properties["wWWHomepage"].Count > 0 ? SearchResult.Properties["wWWHomepage"][0].ToString() : "";
                return homepage;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["wWWHomepage"].Clear();
                if (value != "")
                {
                    de.Properties["wWWHomepage"].Insert(0, value);
                    homepage = value;
                }
                else
                    homepage = null;

                de.CommitChanges();
            }
        }

        public string Province
        {
            get
            {
                if (province == null)
                    province = SearchResult.Properties["st"].Count > 0 ? SearchResult.Properties["st"][0].ToString() : "";
                return province;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["st"].Clear();
                if (value != "")
                {
                    de.Properties["st"].Insert(0, value);
                    province = value;
                }
                else
                    province = null;

                de.CommitChanges();
            }
        }

        public string Street
        {
            get
            {
                if (street == null)
                    street = SearchResult.Properties["streetAddress"].Count > 0 ? SearchResult.Properties["streetAddress"][0].ToString() : "";
                return street;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["streetAddress"].Clear();
                if (value != "")
                {
                    de.Properties["streetAddress"].Insert(0, value);
                    street = value;
                }
                else
                    street = null;

                de.CommitChanges();
            }
        }

        public string Place
        {
            get
            {
                if (place == null)
                    place = SearchResult.Properties["l"].Count > 0 ? SearchResult.Properties["l"][0].ToString() : "";
                return place;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["l"].Clear();
                if (value != "")
                {
                    de.Properties["l"].Insert(0, value);
                    place = value;
                }
                else
                    place = null;

                de.CommitChanges();
            }
        }

        public string Office
        {
            get
            {
                if (office == null)
                    office = SearchResult.Properties["physicalDeliveryOfficeName"].Count > 0 ? SearchResult.Properties["physicalDeliveryOfficeName"][0].ToString() : "";
                return office;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["physicalDeliveryOfficeName"].Clear();
                if (value != "")
                {
                    de.Properties["physicalDeliveryOfficeName"].Insert(0, value);
                    office = value;
                }
                else
                    office = null;

                de.CommitChanges();
            }
        }

        public string DisplayName
        {
            get
            {
                if (displayName == null)
                    displayName = SearchResult.Properties["displayName"].Count > 0 ? SearchResult.Properties["displayName"][0].ToString() : "";
                return displayName;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["displayName"].Clear();
                if (value != "")
                {
                    de.Properties["displayName"].Insert(0, value);
                    displayName = value;
                }
                else
                    displayName = null;

                de.CommitChanges();
            }
        }
        
        public string Country
        {
            get
            {
                if (country == null)
                    country = SearchResult.Properties["co"].Count > 0 ? SearchResult.Properties["co"][0].ToString() : "";
                return country;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["co"].Clear();
                if (value != "")
                {
                    de.Properties["co"].Insert(0, value);
                    country = value;
                }
                else
                    country = null;

                de.CommitChanges();
            }
        }

        public string PostalCode
        {
            get
            {
                if (postalCode == null)
                    postalCode = SearchResult.Properties["postalCode"].Count > 0 ? SearchResult.Properties["postalCode"][0].ToString() : "";
                return postalCode;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["postalCode"].Clear();
                if (value != "")
                {
                    de.Properties["postalCode"].Insert(0, value);
                    postalCode = value;
                }
                else
                    postalCode = null;
                de.CommitChanges();
            }
        }

        public string PostOfficeBox
        {
            get
            {
                if (postOfficeBox == null)
                    postOfficeBox = SearchResult.Properties["postOfficeBox"].Count > 0 ? SearchResult.Properties["postOfficeBox"][0].ToString() : "";
                return postOfficeBox;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["postOfficeBox"].Clear();
                if (value != "")
                {
                    de.Properties["postOfficeBox"].Insert(0, value);
                    postOfficeBox = value;
                }
                else
                    postOfficeBox = null;

                de.CommitChanges();
            }
        }

        public string FirstName
        {
            get
            {
                if (firstName == null)
                    firstName = SearchResult.Properties["givenName"].Count > 0 ? SearchResult.Properties["givenName"][0].ToString() : "";
                return firstName;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["givenName"].Clear();
                if (value != "")
                {
                    de.Properties["givenName"].Insert(0, value);
                    firstName = value;
                }
                else
                    firstName = null;

                de.CommitChanges();
            }
        }

        public byte[] JpgPhoto
        {
            get
            {
                if (jpgPhoto == null)
                    if (SearchResult != null)
                        jpgPhoto = (byte[])(SearchResult.Properties["jpegPhoto"].Count > 0 ? SearchResult.Properties["jpegPhoto"][0] : null);
 
                    return jpgPhoto;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                if (value != null)
                {
                    de.Properties["jpegPhoto"].Insert(0, value);
                    jpgPhoto = value;
                }
                else
                {
                    de.Properties["jpegPhoto"].Clear();
                    jpgPhoto = null;
                }

                de.CommitChanges();
            }
        }

        public string LastName
        {
            get
            {
                if (lastName == null)
                    lastName = SearchResult.Properties["sn"].Count > 0 ? SearchResult.Properties["sn"][0].ToString() : "";
                return lastName;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["sn"].Clear();
                if (value != "")
                {
                    de.Properties["sn"].Insert(0, value);
                    lastName = value;
                }
                else
                    lastName = null;

                de.CommitChanges();
            }
        }
        
        public string Mail
        {
            get
            {
                if(mail==null)
                    mail= SearchResult.Properties["mail"].Count > 0 ? SearchResult.Properties["mail"][0].ToString() : "";
                return mail;
            }
            set
            {
                DirectoryEntry de = SearchResult.GetDirectoryEntry();
                de.Properties["mail"].Clear();
                if (value != "")
                {
                    de.Properties["mail"].Insert(0, value);
                    mail = value;
                }
                else
                    mail = null;

                de.CommitChanges();
            }
        }

        public string AllStringProps
        {
            get
            {
                return Mail + CN;
            }
        }

        public override string ToString()
        {
            return cn;
        }


        public void Save(DirectoryEntry de)
        {
            try
            {
                DirectoryEntry myDirectoryEntry = de.Children.Add("CN=" + cn, "user");
                myDirectoryEntry.Properties["sAMAccountName"].Value = sAMAccountName;
                myDirectoryEntry.Properties["cn"].Value = cn;
                myDirectoryEntry.CommitChanges();
                myDirectoryEntry.Close();
            }
            catch (Exception exc)
            {
                
            }

        }

        public void SetPassword(string p)
        {
            try
            {
                using (DirectoryEntry de = DirectoryEntry)
                {
                    de.Invoke("SetPassword", new object[] { p });
                    de.Properties["userAccountControl"].Value = 1;
                    de.CommitChanges();
                }
            }
            catch (Exception)
            {
                throw new Exception("Cannot set password");
            }
        }
    }
}
